package MultiThread.SequentialControl;

/**
 * @author Jimmy Zhan WORKSTATION
 * @since 2023/8/4 22:05
 * 说明：
 *      控制线程执行顺序  ——  wait + notify
 */

public class WaitNotify {
    // 使用 wait-notify 做一个同步
    static final Object lock = new Object();
    static boolean t2runned = false;     // 表示 t2线程是否运行过
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            // 让 t1 判断 t2是否已经运行过了，如果 t2 没有运行过，就一直等待
            // 给上面我们创建的锁对象lock加synchronized锁，不满足就让t1一直wait()
            synchronized (lock) {
                while (!t2runned) {
                    try {
                        // 线程在wait()的时候会把锁释放开
                        lock.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
            // 条件满足了，t1才开始打印
            System.out.println("1");
        }, "t1");
        Thread t2 = new Thread(() -> {
            // t1那边加了同步块，t2这边也要加一个同步块，保证代码的执行顺序
            synchronized (lock){        // t1那边进了wait()会释放锁，t2就可以在此时获得锁，就可以开始打印
                System.out.println("2");
                // 等 t2打印完了，再通知 t1醒过来
                t2runned = true;
                lock.notify();      // 如果是t2本来就比t1先执行，这里的notify就是一个空唤醒了，因为此时lock里没有等待的线程，无所谓
            }
        }, "t2");

        t1.start();
        t2.start();
    }
}
